package cn.wolfcode.service.impl;

import cn.wolfcode.domain.Destination;
import cn.wolfcode.domain.Region;
import cn.wolfcode.domain.Strategy;
import cn.wolfcode.domain.StrategyCatalog;
import cn.wolfcode.exception.LogicException;
import cn.wolfcode.query.DestinationQuery;
import cn.wolfcode.repsitory.DestinationRepsitory;
import cn.wolfcode.service.IDestinationService;
import cn.wolfcode.service.IRegionService;
import cn.wolfcode.service.IStrategyCatalogService;
import cn.wolfcode.service.IStrategyService;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @Description: Destination业务逻辑实现类
 * @Author: 伍家钰
 * @Date: 2020/8/7 16:20
 * @Version: 1.0
 */
@Service
public class DestinationServiceImpl implements IDestinationService {
    @Resource
    private DestinationRepsitory destinationRepsitory;
    @Resource
    private IRegionService regionService;
    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private IStrategyCatalogService strategyCatalogService;
    @Resource
    private IStrategyService strategyService;

    @Override
    public void save(Destination destination) {
        destinationRepsitory.save(destination);
    }

    @Override
    public void delete(String id) {
        destinationRepsitory.deleteById(id);
    }

    @Override
    public void update(Destination destination) {
        destinationRepsitory.save(destination);
    }

    @Override
    public Destination get(String id) {
        return destinationRepsitory.findById(id).orElse(null);
    }

    @Override
    public List<Destination> list() {
        return destinationRepsitory.findAll();
    }

    /**
     * 根据区域id查询关联的目的地集合
     *
     * @param rid:
     * @return
     */
    @Override
    public List<Destination> queryDestByRefIds(String rid) {
        // 1.获取目的地对象
        Region region = regionService.get(rid);
        // 2.获取区域中的目的地id集合
        List<String> refIds = region.getRefIds();
        // 3.查询出id在list集合范围中的区域对象的集合
        return destinationRepsitory.findByIdIn(refIds);
    }

    @Override
    public Page<Destination> query(DestinationQuery qo) {
        Query query = new Query();
        // 查询数据总条数
        long total = mongoTemplate.count(query, Destination.class);
        if (total == 0) {
            // 如果返回null会报错
            return Page.empty();
        }
        // 当前页显示的数据,Pageable是PageRequest的父接口的父接口
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");
        if (StringUtils.hasText(qo.getParentId())) {
            Criteria criteria = Criteria.where("parentId").is(qo.getParentId());
            // 拼接高查条件
            query.addCriteria(criteria);
        } else {
            Criteria criteria = Criteria.where("parentId").is(null);
            // 拼接高查条件
            query.addCriteria(criteria);
        }
        if (StringUtils.hasText(qo.getKeyword())) {
            Criteria criteria = Criteria.where("name").regex(".*" + qo.getKeyword().replace(" ", "") + ".*");
            // 拼接高查条件
            query.addCriteria(criteria);
        }
        // 拼接分页条件
        query.with(pageable);
        // 执行语句
        List<Destination> list = mongoTemplate.find(query, Destination.class, "destination");
        return new PageImpl<>(list, pageable, total);
    }

    @Override
    public void updateInfo(String id, String info) {
        // 先根据id查询出目的地对象
        Optional<Destination> optional = destinationRepsitory.findById(id);
        // 如果查询对象不存在则返回null
        if (optional.orElse(null) == null) {
            throw new LogicException("目的地不存在,请联系管理员更新数据");
        }
        // 目的地对象存在则获取目的地对象
        Destination destination = optional.get();
        // 跟新目的地简介,全局更新
        destination.setInfo(info);
        destinationRepsitory.save(destination);
    }

    @Override
    public List<Destination> queryToast(String destId) {
        List<Destination> list = new ArrayList<>();
        this.createToast(list, destId);
        Collections.reverse(list);
        return list;
    }

    /**
     * 递归
     *
     * @param list
     * @param destId
     */
    private void createToast(List<Destination> list, String destId) {
        if (!StringUtils.hasText(destId)) {
            return;
        }
        Destination dest = this.get(destId);
        list.add(dest);
        if (StringUtils.hasText(dest.getParentId())) {
            this.createToast(list, dest.getParentId());
        }
    }

    @Override
    public List<Destination> queryDestByRefIdsForApi(String regionId) {
        List<Destination> list = null;
        if ("-1".equals(regionId)) {
            // 根据名称查询目的地集合
            list = destinationRepsitory.findByParentName("中国");
        } else {
            list = this.queryDestByRefIds(regionId);
        }
        // 遍历集合
        for (Destination dest : list) {
            // 查询父类id是当前目的地的,目的地集合
            List<Destination> childrens = destinationRepsitory.findByParentId(dest.getId());
            // 将查出的结果封装到目的地对象的Children属性中
            dest.setChildren(childrens);
        }
        return list;
    }

    @Override
    public List<StrategyCatalog> queryCatalogs(String destId) {
        // 先根据id查询出所有destId为广州的攻略分类对象集合
        List<StrategyCatalog> catalogs = strategyCatalogService.findByDestId(destId);
        // 遍历集合根据catalogId拿出catalogs集合中每个攻略对象对象
        for (StrategyCatalog catalog : catalogs) {
            String catalogId = catalog.getId();
            List<Strategy> strategys = strategyService.findByCatalogId(catalogId);
            catalog.setStrategies(strategys);
        }
        return catalogs;
    }
}
